﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pets.Abstract
{
    /// <summary>
    /// Абстрактный класс, для загрузки\сохранения  List<Animal>
    /// </summary>
    public abstract class Serializer : ISerializer
    {
        #region Методы интерфейса

        public abstract List<Concrete.Animal> Load(string filename);

        public abstract void Save(string filename, List<Concrete.Animal> list_animal);

        #endregion

        /// <summary>
        /// Создание объекта Animal из хмл-дерева
        /// </summary>
        public object BuildTree(ClassTag parent)
        {
            /// <summary>
            /// Определение типа объекта parent и создание его экземпляра с пустым конструктором
            /// </summary>
            Type parent_type = null;
            if (parent.Name == "PetAviary")
            {
                parent_type = typeof(Aviary);
            }
            else
            {
                parent_type = Type.GetType("Pets.Concrete." + parent.Name);
            }
            object this_class = Activator.CreateInstance(parent_type);

            /// <summary>
            /// Поиск дочерних елементов созданного класса.
            /// Если тип дочернего свойства примитивный - устанавливаем его,
            /// иначе рекурсивно вызываем метод.
            /// </summary>
            foreach (ITag tag in parent.Children)
            {
                if (tag.GetType() == typeof(PropTag))
                {
                    Type t = this_class.GetType().GetProperty(tag.Name).PropertyType;
                    if (t == typeof(System.String))
                    {
                        this_class.GetType().GetProperty(tag.Name).SetValue(this_class, (tag as PropTag).Value, null);
                    }
                    if (t == typeof(System.Int32))
                    {
                        this_class.GetType().GetProperty(tag.Name).SetValue(this_class, Convert.ToInt32((tag as PropTag).Value), null);
                    }
                }
                else
                {
                    this_class.GetType().GetProperty(tag.Name).SetValue(this_class, this.BuildTree(tag as ClassTag), null);
                }
            }
            return this_class;

        }


    }
}
